﻿/*
   Copyright 2011 Softisis

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FOM.Impl;
using FOM.Impl.Converters;
using FOM.Interfaces;
using NUnit.Framework;

namespace TestUnits
{
    /// <summary>
    /// For standard and nominal tests
    /// </summary>
    /// <remarks>Copyright Softisis 2011 (France)</remarks>
    [TestFixture]
    public class TypeOverrideMappingsTests
    {


        [SetUp]
        public void SetUp()
        {
        }

        /// <summary>
        /// tests the fact that we want to replace an implementation by another,
        /// and map one of the value from the source to the target
        /// </summary>
        [Test]
        public void TestInterfaceReplacementAndMapping()
        {
            // create manager
            IManager mngr = new ManagerImpl();

            IMappingNode<ObjectC, ObjectC> rootmap = mngr.RegisterMapping<ObjectC, ObjectC>("test");
            rootmap.Map(a => a.IoD, b => b.IoD).OverrideSourceType<ObjDImpl1>()
                .OverrideTargetType<ObjDImpl2>().NewInstance() // new instance is required because Override on a property
                .Map(t=>t.Str, y=>y.Double).UseConverter(new StringToValueTypesConv()); // we replace implementation of IObjC, and we copy int into double

            // srouce object
            var srcC = TestObjectsHolder.GetObjectC();
            ObjectC res = (ObjectC)mngr.ApplyMapping("test", srcC);

            Assert.IsTrue(res!=null);
            Assert.IsTrue(res.IoD!=null);
            Assert.IsTrue(res.IoD.GetType() == typeof(ObjDImpl2));
            Assert.IsTrue(((ObjDImpl2)(res.IoD)).Double == 789456);
        }

        /// <summary>
        /// This method test the type replacement after a goto and then a mapping on the target.
        /// It lokk like previous one, but there is no mapping on the overriding type, but a simple GoTo.
        /// </summary>
        [Test]
        public void TestInterfaceReplacementAndMappingWithGoto()
        {
            // create manager
            IManager mngr = new ManagerImpl();

            IMappingNode<ObjectC, ObjectC> rootmap = mngr.RegisterMapping<ObjectC, ObjectC>("test");
            rootmap.GoTo(a => a.IoD, b => b.IoD).OverrideSourceType<ObjDImpl1>()
                .OverrideTargetType<ObjDImpl2>() // new instance NOT required because overriding on a path element, not a property itself
                .Map(t => t.Str, y => y.Double).UseConverter(new StringToValueTypesConv()); // we replace implementation of IObjC, and we copy int into double

            // srouce object
            var srcC = TestObjectsHolder.GetObjectC();
            ObjectC res = (ObjectC)mngr.ApplyMapping("test", srcC);

            Assert.IsTrue(res != null);
            Assert.IsTrue(res.IoD != null);
            Assert.IsTrue(res.IoD.GetType() == typeof(ObjDImpl2));
            Assert.IsTrue(((ObjDImpl2)(res.IoD)).Double == 789456);
        }


        /// <summary>
        /// This method test the type replacement after a goto and then a mapping on the target.
        /// It lokk like previous one, but there is no mapping on the overriding type, but a simple GoTo.
        /// </summary>
        [Test]
        public void TestInterfaceReplacementWithCustomConverter()
        {
            // create manager
            IManager mngr = new ManagerImpl();

            IMappingNode<ObjectC, ObjectC> rootmap = mngr.RegisterMapping<ObjectC, ObjectC>("test");
            rootmap.Map(a => a.IoD, b => b.IoD)
                .NewInstance()
                .OverrideSourceType<ObjDImpl1>() // source override
                .OverrideTargetType<ObjDImpl2>() // target override: we replace implementation of IObjC
                .UseConverter(new Ci1toCi2());   // and we copy int into double using converter

            // srouce object
            var srcC = TestObjectsHolder.GetObjectC();
            ObjectC res = (ObjectC)mngr.ApplyMapping("test", srcC);

            Assert.IsTrue(res != null);
            Assert.IsTrue(res.IoD != null);
            Assert.IsTrue(res.IoD.GetType() == typeof(ObjDImpl2));
            Assert.IsTrue(((ObjDImpl2)(res.IoD)).Double == 789456);
        }

    }
}
